<html>
<head>
<title>CpcPaChi - Version 0.08</title>
<style type="text/css">
span {
	font-family: 'Courier New';
	font-size: 10pt;
	color: #000000;
}
.sc0 {
	color: #808080;
}
.sc3 {
	color: #008080;
}
.sc4 {
	color: #FF8000;
}
.sc5 {
	font-weight: bold;
	color: #0000FF;
}
.sc7 {
	color: #808080;
}
.sc9 {
	color: #804000;
}
.sc10 {
	font-weight: bold;
	color: #000080;
}
.sc11 {
}
</style>
</head>
<body>
<h2>Un compilador sencillo paso a paso (8 - Mejorando el analizador l&eacute;xico)</h2>

<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>

<p>Nuestro analizador l&eacute;xico es capaz de leer un cierto s&iacute;mbolo del c&oacute;digo fuente, de obtener un identificador o un n&uacute;mero entero. Es la base de lo que necesitamos, pero a&uacute;n tiene carencias. Dos de ellas son especialmente graves:</p>

<ul>
  <li>Es habitual que los identificadores permitan usar letras y n&uacute;meros (por ejemplo, "variable01" deber&iacute;a ser un nombre correcto para una variable), con la restricci&oacute;n de que el primer s&iacute;mbolo sea una letra, no un n&uacute;mero. Nuestro analizador por ahora s&oacute;lo permite que est&eacute;n formados por letras.</li>
  <li>No permite usar comentarios en el c&oacute;digo fuente.</li>
</ul>

<p>El primer cambio, en la forma de definir los identificadores, es sencillo, apenas una modificaci&oacute;n peque&ntilde;a en la funci&oacute;n "obtenerIdentificador":</p>

<pre><code>
// Un identificador debe empezar por letra
if ( (letra &gt;= 'A') &amp;&amp; (letra &lt;= 'Z') )
{
  do
  {
      lexema += letra;
      letra = (&quot;&quot;+ObtenerLetra()).ToUpper()[0];
  }  // Y puede seguir por letra o cifra num&eacute;rica
  while  ( ( (letra &gt;= 'A') &amp;&amp; (letra &lt;= 'Z') ) 
    || ( (letra &gt;= '0') &amp;&amp; (letra &lt;= '9') ) );
}
// He leido uno de mas, asi que retrocedo
if (posicionLineaActual &gt; 0)
  posicionLineaActual --;
</code></pre>

<p>El segundo cambio tampoco es mucho m&aacute;s dif&iacute;cil: si un comentario empieza en llave debemos saltar todo hasta encontrar una llave cerrada (este cambio ser&aacute; parte de "saltarBlancos"), as&iacute;:</p>

<pre><code>
// Salto comentarios entre llaves
if ( proximaLetra == '{')
{
  do
    proximaLetra = ObtenerLetra();
  while ( proximaLetra != '}');
  
  proximaLetra = ObtenerLetra(); // Salto la llave de cierre
}
</code></pre>

<p>Y de forma similar, aunque un poco m&aacute;s larga porque hay que mirar hacia adelante dos caracteres, saltar&iacute;amos los comentarios entre (* y *):</p>

<pre><code>
// Salto comentarios con par&eacute;ntesis-asterisco
if ( ( proximaLetra == '(')
 &amp;&amp; (posicionLineaActual &lt; lineaActual.Length)
 &amp;&amp; (lineaActual[posicionLineaActual] == '*') )    
{
  if (depurando)
    Console.WriteLine(&quot;  Comentario con par&eacute;ntesis-asterisco&quot;);
  do
    proximaLetra = ObtenerLetra();
  while ( ( proximaLetra != '*')
    || ( (posicionLineaActual &lt; lineaActual.Length-1)
    &amp;&amp; (lineaActual[posicionLineaActual] != ')')) );
  
  proximaLetra = ObtenerLetra(); // Salto el asterisco
  proximaLetra = ObtenerLetra(); // Salto el par&eacute;ntesis de cierre
}
</code></pre>


<p>Por supuesto, quedan muchas cosas por hacer. Nuestro analizador empieza a reconocer correctamente los programas que no tengan fallos, pero es muy torpe en el manejo de errores. Es habitual crear un tipo de datos llamado "Token", de forma que de cada elemento que leamos (ya sea identificador, n&uacute;mero entero, s&iacute;mbolo matem&aacute;tico, etc) sepamos otros datos, como la posici&oacute;n del fichero en que se encuentra (para que los mensajes de error sean m&aacute;s correctos), el tipo de elemento del que se trata, su valor, etc. Lo b&aacute;sico que necesitar&iacute;amos ser&iacute;a algo como:</p>

<pre><code>
type token =
  record
    tipoToken: integer;
    valor: string;
    posx,posy: integer;
  end;
</code></pre>

<p>Aun as&iacute;, esto son mejoras sin las cuales nuestro compilador puede funcionar "relativamente bien" al nivel que nos interesa por ahora, es decir, si nosotros somos cuidadosos tecleando los fuentes, porque los mensajes de error ser&aacute;n muy poco aclaradores.</p>

<p>En la pr&oacute;xima entrega mejoraremos nuestra tabla de s&iacute;mbolos y empezaremos a usar variables, cuyo valor pueda realmente ser modificado durante el funcionamiento del programa.</p>

<p>Y posiblemente alg&uacute;n d&iacute;a completaremos el analizador l&eacute;xico para que sea m&aacute;s fiable... posiblemente...</p>

<p><br>Como siempre, para m&aacute;s detalles, todo el c&oacute;digo est&aacute; en la p&aacute;gina del proyecto en Google Code:<br /><br /><a href="http://code.google.com/p/cpcpachi/">http://code.google.com/p/cpcpachi/</a></p>

<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
</body>
</html>
